home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’96 / Talking Telnet / source / Screens / rsinterf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-22  |  44.4 KB  |  1,588 lines  |  [TEXT/CWIE]

  1. /* rsinterf.c */
  2.  
  3. /* A split of RSmac.c to facilitate keeping my sanity --CCP */
  4.  
  5. #include "rsdefs.h"
  6. #include "vsdata.h"
  7. #include "wind.h"
  8. #include "rsmac.proto.h"
  9. #include "vsinterf.proto.h"
  10. #include "vsintern.proto.h"
  11. #include "rsinterf.proto.h"
  12. #include "menuseg.proto.h"
  13. #include "maclook.proto.h"
  14. #include "wdefpatch.proto.h"    /* 931112, ragge, NADA, KTH */
  15. #include "parse.proto.h"
  16. #include "network.proto.h"
  17. #include "DlogUtils.proto.h"
  18. #include "url.proto.h"
  19. #include "drag.proto.h"
  20. #include "configure.proto.h"
  21. #include "errors.proto.h"
  22. #include "speech.proto.h"
  23.  
  24.  
  25. static void calculateWindowPosition(WindRec *theScreen,Rect *whereAt, short colsHigh, short colsWide);
  26.  
  27. extern WindRec *screens;
  28.  
  29. extern short MaxRS;
  30. extern RSdata *RSlocal, *RScurrent;
  31. extern Rect    noConst;
  32. extern short RSw,         /* last window used */
  33.     RSa;          /* last attrib used */
  34. extern  short **topLeftCorners;
  35. extern short    NumberOfColorBoxes;
  36. extern short    BoxColorItems[8];
  37. extern RGBColor    BoxColorData[8];
  38.  
  39. long RScolors[8] =    //these are the old quickdraw constants, 
  40. {                    //only used if Telinfo->hasColorQuickDraw is false 
  41.     blackColor,        
  42.     redColor,        
  43.     greenColor,            
  44.     yellowColor,    
  45.     blueColor,        
  46.     magentaColor,    
  47.     cyanColor,            
  48.     whiteColor
  49. };
  50.  
  51.  
  52. SIMPLE_UPP(ScrollProc,ControlAction);
  53.  
  54. static void HandleDoubleClick(short w, short modifiers);
  55.  
  56. void    RSunload(void) {}
  57.  
  58.  
  59. /*------------------------------------------------------------------------------*/
  60. /* RSselect                                                                        */
  61. /* Handle the mouse down in the session window.  All we know so far is that it    */
  62. /* is somewhere in the content window, and it is NOT an option - click.            */
  63. /* Double clicking now works -- SMB                                                */
  64. // And I fixed it so it works correctly.  Grrrr... - JMB
  65. //    WARNING: Make sure RSlocal[w].selected is 1 when doing selections.  If it is
  66. //        zero, the autoscrolling routines will seriously hose the selection drawing.
  67. //        Heed this advice, it took me two hours to find the cause of this bug! - JMB
  68.  
  69.   /* called on a mouse-down in the text display area of the
  70.     active window. Creates or extends the highlighted selection
  71.     within that window, autoscrolling as appropriate if the user
  72.     drags outside the currently visible part of the display. */
  73. void RSselect( short w, Point pt, EventRecord theEvent)
  74. {
  75.     static    long     lastClick = 0;
  76.     static     Point     lastClickLoc = {0,0};
  77.     GrafPtr tempwndo;
  78.     Point    curr, temp;
  79.     long    clickTime;
  80.     short    shift = (theEvent.modifiers & shiftKey);
  81.     RSsetConst(w);
  82.     tempwndo = RSlocal[w].window;
  83.     
  84.     curr = normalize(pt, w, TRUE);
  85.     clickTime = TickCount();
  86.     
  87.     if  ( ( EqualPt(RSlocal[w].anchor, curr) || EqualPt(RSlocal[w].anchor, RSlocal[w].last) )
  88.             &&  ((clickTime - lastClick) <= GetDblTime())
  89.             && EqualPt(curr, lastClickLoc)) {
  90.         /* NCSA: SB - check to see if this is a special click */
  91.         /* NCSA: SB - It has to be in the right time interval, and in the same spot */
  92.         curr = RSlocal[w].anchor = RSlocal[w].last = normalize(pt, w,TRUE);
  93.         HandleDoubleClick(w, theEvent.modifiers);
  94.         RSlocal[w].selected = 1;
  95.         lastClick = clickTime;
  96.         lastClickLoc = curr;
  97.         }
  98.     else if (theEvent.modifiers & cmdKey)
  99.     { // a command click means we should look for a url
  100.         if ((RSlocal[w].selected)&(PointInSelection(curr, w))) //we have a selection already 
  101.             HandleURL(w);
  102.         else
  103.         { // we need to find the url around this pnt
  104.             if (FindURLAroundPoint(curr, w))
  105.                 HandleURL(w);
  106.             else
  107.                 SysBeep(1);
  108.         }
  109.     }
  110. #ifdef    CONTROLKEYSPEECH
  111.     else if (theEvent.modifiers & controlKey)
  112.     {
  113.         SpeakSelectedText(w);
  114.     }
  115. #endif    /* CONTROLKEYSPEECH */    
  116.     else {
  117.         lastClick = clickTime;
  118.         lastClickLoc = curr;
  119.         if (RSlocal[w].selected) {
  120.             if (!shift) {
  121.               /* unhighlight current selection */
  122.                 RSinvText(w, RSlocal[ w].anchor, RSlocal[w].last, &noConst);
  123.               /* start new selection */
  124.                 curr = RSlocal[w].last = RSlocal[w].anchor = normalize(pt, w,TRUE);
  125.             }
  126.             else {
  127.                 RSsortAnchors(w);
  128.                 if ((curr.v < RSlocal[w].anchor.v) || ((curr.v == RSlocal[w].anchor.v) && (curr.h < RSlocal[w].anchor.h))) {
  129.                     temp = RSlocal[w].anchor;
  130.                     RSlocal[w].anchor = RSlocal[w].last;
  131.                     RSlocal[w].last = temp;
  132.                     }
  133.                 }
  134.           }
  135.         else
  136.           {
  137.           /* start new selection */
  138.             curr = RSlocal[w].anchor = RSlocal[w].last = normalize(pt, w,TRUE);
  139.             RSlocal[w].selected = 1;
  140.             }
  141.             
  142.         while (StillDown())
  143.           {
  144.           /* wait for mouse position to change */
  145.             do {
  146.                 curr = normalize(getlocalmouse(tempwndo), w,TRUE);
  147.                 } while (EqualPt(curr, RSlocal[w].last) && StillDown());
  148.     
  149.           /* toggle highlight state of text between current and last mouse positions */
  150.             RSinvText(w, curr, RSlocal[w].last, &noConst);
  151.             RSlocal[w].last = curr;
  152.           } /* while */
  153.         }
  154.  
  155.     
  156.     if (EqualPt(RSlocal[w].anchor, RSlocal[w].last)) RSlocal[w].selected = 0;
  157.         else RSlocal[w].selected = 1;
  158.     SetMenusForSelection((short)RSlocal[w].selected);
  159.   } /* RSselect */
  160.   
  161.   void FlashSelection(short w)
  162.   {
  163.     short i;
  164.     long finalTick;
  165.     for (i = 0; i < 2; i++) {
  166.         Delay(5, &finalTick);
  167.             RSinvText(w, RSlocal[ w].anchor, RSlocal[w].last, &noConst);
  168.         Delay(5, &finalTick);
  169.         RSinvText(w, RSlocal[ w].anchor, RSlocal[w].last, &noConst);
  170.     }
  171.   }
  172.   Boolean PointInSelection(Point curr, short w)
  173.   {
  174.       long beg_offset, end_offset, current_offset;
  175.       short columns;
  176.       columns = VSgetcols(w);
  177.       beg_offset = columns*RSlocal[w].anchor.v + RSlocal[w].anchor.h;
  178.       end_offset = columns*RSlocal[w].last.v + RSlocal[w].last.h;
  179.       if (beg_offset == end_offset)
  180.           return FALSE;
  181.       current_offset = columns*curr.v + curr.h;
  182.     if ((current_offset >= beg_offset)&&(current_offset <= end_offset))
  183.           return TRUE;
  184.       else
  185.           return FALSE;
  186.   }
  187.   void RSzoom
  188.   (
  189.     GrafPtr window, /* window to zoom */
  190.     short code, /* inZoomIn or inZoomOut */
  191.     short shifted /* bring to front or not */
  192.   )
  193.   /* called after a click in the zoom box, to zoom a terminal window. */
  194.   {
  195.     WStateData    **WSDhdl;
  196.     short        w;
  197.     short        h, v, x1, x2, y1, y2;
  198.     short        width, lines;            // For setting Standard State before zooming
  199.     short        top, left;                // Ditto
  200.     
  201.     SetPort(window);
  202.     w = RSfindvwind(window); /* which window is it, anyway */
  203.  
  204.     width = VSmaxwidth(w) + 1;
  205.     lines = VSgetlines(w);
  206.     WSDhdl = (WStateData **)((WindowPeek)window)->dataHandle;
  207.     top = (**WSDhdl).userState.top;
  208.     left = (**WSDhdl).userState.left;
  209.     HLock((Handle)WSDhdl);
  210.     SetRect(&((*WSDhdl)->stdState), left, top, RMAXWINDOWWIDTH + left,
  211.                 RMAXWINDOWHEIGHT + top);
  212.     HUnlock((Handle)WSDhdl);
  213.     
  214.     /* EraseRect(&window->portRect); */
  215.     ZoomWindow(window, code, shifted);
  216.     EraseRect(&window->portRect);            /* BYU 2.4.15 */
  217.  
  218.   /* get new window size */
  219.     h = window->portRect.right - window->portRect.left;
  220.     v = window->portRect.bottom - window->portRect.top;
  221.  
  222.     RSsetsize(w, v, h); /* save new size settings and update scroll bars */
  223.   /* update the visible region of the virtual screen */
  224.     VSgetrgn(w, &x1, &y1, &x2, &y2);
  225.     VSsetrgn(w, x1, y1, (x1 + (h - 16 + CHO) / FWidth -1),
  226.         (y1 + (v - 16 + CVO) / FHeight - 1));
  227.     VSgetrgn(w, &x1, &y1, &x2, &y2);        /* Get new region */
  228.   /* refresh the part which has been revealed, if any */
  229.     VSredraw(w, 0, 0, x2 - x1 + 1, y2 - y1 + 1); 
  230.   /* window contents are now completely valid */
  231.     ValidRect(&window->portRect);
  232.   } /* RSzoom */
  233.   
  234. Boolean RSisInFront(short w)
  235. {
  236.     if (((WindowPtr)RSlocal[w].window) == FrontWindow())
  237.         return TRUE;
  238.     else
  239.         return FALSE;
  240. }
  241.  
  242.   short RSupdate
  243.   (
  244.     GrafPtr wind
  245.   )
  246.   /* does updating for the specified window, if it's one of mine.
  247.     Returns zero iff it is. */
  248.   {
  249.     short w, x1, x2, y1, y2;
  250.  
  251.     w = RSfindvwind(wind);
  252.     if (RSsetwind(w) < 0)
  253.         return(-1); /* not one of mine */
  254.     BeginUpdate(wind);
  255.     RSregnconv /* find bounds of text area needing updating */
  256.       (
  257.         wind->visRgn,
  258.         &x1, &y1, &x2, &y2,
  259.         RScurrent->fheight, RScurrent->fwidth
  260.       );
  261.     if (x2 > x1)
  262.     {
  263.         VSredraw(w, x1, y1, x2, y2); /* draw that text */
  264.       /* We must reset, less we risk looking UGLY as sin... */
  265.         BackPat(PATTERN(qd.white));
  266.         PenPat(PATTERN(qd.black));
  267.         if (TelInfo->haveColorQuickDraw)
  268.           {
  269.             PmForeColor(0);
  270.             PmBackColor(1);
  271.           }
  272.         else
  273.           {
  274.             if (!RSlocal->flipped)
  275.             {
  276.                 ForeColor(RScolors[0]);        /* normal foreground */
  277.                 BackColor(RScolors[7]);        /* normal Background */
  278.               }
  279.               else    
  280.             {
  281.                 ForeColor(RScolors[7]);        /* normal foreground */
  282.                 BackColor(RScolors[0]);        /* normal Background */
  283.               }
  284.           } /* if */
  285.         //now get that annoying strip on the right (CCP)
  286.         RSa = -1;
  287.         PenMode(patOr);
  288.         DrawGrowIcon(wind);
  289.         PenMode(patCopy);
  290.         //DrawControls(wind);
  291.         UpdtControl(wind, wind->visRgn);
  292.     }
  293.     EndUpdate(wind);
  294.     return(0);
  295.   } /* RSupdate */
  296.   
  297.   short RSTextSelected(short w) {        /* BYU 2.4.11 */
  298.   return(RSlocal[w].selected);    /* BYU 2.4.11 */
  299. }                                /* BYU 2.4.11 */
  300.  
  301. void RSskip
  302.   (
  303.     short w,
  304.     Boolean on
  305.   )
  306.   /* sets the "skip" flag for the specified window (whether ignore
  307.     screen updates until further notice). */
  308.   {
  309.     RSlocal[w].skip = on;
  310.   } /* RSskip */
  311.  
  312.  
  313.   /*
  314. *  This routine is called when the user presses the grow icon, or when the size of
  315. *  the window needs to be adjusted (where==NULL, modifiers==0).
  316. *  It limits the size of the window to a legal range.
  317. */
  318.  
  319. short RSsize (GrafPtr window, long *where, long modifiers)
  320. {
  321.     Rect    SizRect;
  322.     long    size;
  323.     short    w, width, lines;
  324.     short    tw, h, v, x1, x2, y1, y2, th;
  325.     Boolean    changeVSSize = false;
  326.     short    screenIndex = 0;
  327.     Boolean    screenIndexValid = false;
  328.     short     err = noErr;
  329.     if ((w = RSfindvwind(window)) < 0)    /* Not found */
  330.         return (0);
  331.     
  332.     if (modifiers & cmdKey) return (0);
  333.     
  334.     screenIndexValid = (screenIndex = findbyVS(w)) != -1;
  335.  
  336.     changeVSSize = (modifiers & optionKey) == optionKey;
  337.  
  338. #define DONT_DEFAULT_CHANGE_VS_IF_NAWS                // JMB
  339.     // 931112, ragge, NADA, KTH 
  340.     // I think this is the way it should work, if there is naws available it
  341.     // should be used by default, and option toggles behaviour.
  342.     // Maybe it should be user configurable?
  343. #ifndef DONT_DEFAULT_CHANGE_VS_IF_NAWS
  344.     if(screenIndexValid && screens[screenIndex].naws) {
  345.         changeVSSize = (modifiers & optionKey) != optionKey;
  346.     }
  347. #endif
  348.  
  349.     SetPort(window);
  350.  
  351.     width = VSmaxwidth(w) + 1; //VSmaxwidth returns one less than number of columns
  352.     lines = VSgetlines(w);
  353.  
  354.  
  355.     if (changeVSSize) {
  356.         th = INFINITY;
  357.         tw = INFINITY-1;
  358.         }
  359.     else {
  360.         tw = RMAXWINDOWWIDTH;
  361.         th = RMAXWINDOWHEIGHT + 1;
  362.         }
  363.  
  364.     SetRect(&SizRect, 48, 48, tw + 1, th);
  365.     
  366.     if (where)                                            /* grow icon actions */
  367.         {                            
  368.         if (changeVSSize) { /* 931112, ragge, NADA, KTH */
  369.             setupForGrow(window, 1 - CHO, 1 - CVO, FWidth, FHeight);
  370.         }
  371.         size = GrowWindow(window, *(Point *) where, &SizRect);    /* BYU LSC */
  372.         if (changeVSSize) { /* 931112, ragge, NADA, KTH */
  373.             cleanupForGrow(window);
  374.         }
  375.  
  376.         if (size != 0L)
  377.           {
  378.             SizeWindow(window, size & 0xffff, (size >> 16) & 0xffff, FALSE);
  379.             h = window->portRect.right - window->portRect.left;
  380.             v = window->portRect.bottom - window->portRect.top;
  381.           }
  382.         else return(0);                            /* user skipped growing */
  383.       }
  384.     else
  385.       {                                    /* just resize the window */
  386.         h = window->portRect.right - window->portRect.left;    /* same width */
  387.         v = (FHeight) * (VSgetlines(w));                    /* new height */
  388.         SizeWindow(window, h, v, FALSE);                    /* change it */
  389.         }     
  390.  
  391.     RSsetsize(w, v, h); /* save new size settings and update scroll bars */
  392.  
  393.     
  394.   /* update the visible region of the virtual screen */
  395.  
  396.     VSgetrgn(w, &x1, &y1, &x2, &y2);
  397.     VSsetrgn(w, x1, y1, (short)((x1 + (h - 16 + CHO) / FWidth - 1)),
  398.         (short)((y1 + (v - 16) / FHeight - 1)));
  399.     VSgetrgn(w, &x1, &y1, &x2, &y2);        /* Get new region */
  400.  
  401.     if (changeVSSize) {
  402.         
  403.         switch (VSsetlines(w,y2 -y1 +1)) {
  404.  
  405.  
  406.         case (-4000): //can't even get enough memory to put VS back to original size
  407.             /* signal this to main program */
  408.             return(-4);
  409.             break;
  410.         
  411.         case (-3000): //no resize: unkown problems, but we put the VS back to original size
  412.             return(0);
  413.             break;
  414.         case (-2000): //no resize: Memory problems, but we put the VS back to original size
  415.             return(-2);
  416.             break;
  417.         default:    //Ok, we can resize; tell host
  418.             RScalcwsize(w,x2 - x1 +1);
  419.             if (screenIndexValid && screens[screenIndex].naws)
  420.                 SendNAWSinfo(&screens[screenIndex], (x2-x1+1), (y2-y1+1));
  421.             return (0);
  422.             break;
  423.         }
  424.     }
  425.  
  426.     VSredraw(w, 0, 0, x2 - x1 + 1, y2 - y1 + 1);        /* refresh the part which has been revealed, if any */
  427.     ValidRect(&window->portRect);                        /* window contents are now completely valid */
  428.  
  429.     return (0);
  430.   } /* RSsize */
  431.   
  432. void RSshow( short w)        /* reveals a hidden terminal window. */
  433. {
  434.     VSscrn *theVS;
  435.     if (RSsetwind(w) < 0)
  436.         return;
  437.     theVS = VSwhereis(w);
  438.     RSa = -1;
  439.     VSredraw(w, 0, 0, theVS->maxwidth, theVS->lines);
  440.     ShowWindow(RScurrent->window);
  441. }
  442.  
  443. Boolean RSsetcolor
  444.     (
  445.     short w, /* window number */
  446.     short n, /* color entry number */
  447.     RGBColor    Color
  448.     )
  449.   /* sets a new value for the specified color entry of a terminal window. */
  450.   {
  451.     if ( !(TelInfo->haveColorQuickDraw) || (RSsetwind(w) < 0) || (n > 5) || (n < 0))
  452.         return(FALSE);
  453.     
  454.     SetEntryColor(RScurrent->pal, n, &Color);
  455.     SetPort(RScurrent->window);
  456.     InvalRect(&RScurrent->window->portRect);
  457.     return(TRUE);
  458.   } /* RSsetcolor */
  459.   
  460.   void RSsendstring
  461.   (
  462.     short w, /* which terminal window */
  463.     char *ptr, /* pointer to data */
  464.     short len /* length of data */
  465.   )
  466.   /* sends some data to the host along the connection associated
  467.     with the specified window. */
  468.   {
  469.     short temp;
  470.  
  471.     temp = findbyVS(w);
  472.     if (temp < 0)
  473.         return;
  474.     netpush(screens[temp].port);                /* BYU 2.4.18 - for Diab systems? */        
  475.     netwrite(screens[temp].port, ptr, len);
  476.   } /* RSsendstring */
  477.  
  478.  
  479. short RSnewwindow
  480.   (
  481.     RectPtr     wDims,
  482.     short scrollback, /* number of lines to save off top */
  483.     short width, /* number of characters per text line (80 or 132) */
  484.     short lines, /* number of text lines */
  485.     StringPtr name, /* window name */
  486.     short wrapon, /* autowrap on by default */
  487.     short fnum, /* ID of font to use initially */
  488.     short fsiz, /* size of font to use initially */
  489.     short showit, /* window initially visible or not */
  490.     short goaway, /* NCSA 2.5 */
  491.     short forcesave,        /* NCSA 2.5: force screen save */
  492.       short screenNumber
  493.   )
  494.   /* creates a virtual screen and a window to display it in. */
  495.   {
  496.     GrafPort gp; /* temp port for getting text parameters */
  497.     short w;
  498.  
  499.     Rect        pRect;
  500.     short        wheight, wwidth;
  501.     WStateData    *wstate;
  502.     WindowPeek    wpeek;
  503.     CTabHandle    ourColorTableHdl;
  504.   /* create the virtual screen */
  505.     w = VSnewscreen(scrollback, (scrollback != 0), /* NCSA 2.5 */
  506.         lines, width, forcesave);    /* NCSA 2.5 */
  507.     if (w < 0) {        /* problems opening the virtual screen -- tell us about it */
  508.         return(-1);
  509.           }
  510.       
  511.     RScurrent = RSlocal + w;
  512.  
  513.     RScurrent->fnum = fnum;
  514.     RScurrent->fsiz = fsiz;
  515.  
  516.     OpenPort(&gp);
  517.     RSTextFont(fnum,fsiz,0);    /* BYU */
  518.     TextSize(fsiz);
  519.     RSfontmetrics();
  520.     ClosePort(&gp);
  521.      
  522.     if (wDims->bottom == 0)
  523.         calculateWindowPosition(&screens[screenNumber],wDims,lines,width);
  524.  
  525.     if ((wDims->right - wDims->left) > RMAXWINDOWWIDTH)
  526.         wDims->right = wDims->left + RMAXWINDOWWIDTH;
  527.     if ((wDims->bottom - wDims->top) > RMAXWINDOWHEIGHT)
  528.         wDims->bottom = wDims->top + RMAXWINDOWHEIGHT;
  529.     wwidth = wDims->right - wDims->left;
  530.     wheight = wDims->bottom - wDims->top;
  531.  
  532.     if (!RectInRgn(wDims,TelInfo->greyRegion)) //window would be offscreen
  533.         calculateWindowPosition(&screens[screenNumber],wDims,lines,width);
  534.  
  535.   /* create the window */
  536.     if (!TelInfo->haveColorQuickDraw) {
  537.         RScurrent->window = NewWindow(0L, wDims, name, showit, 8,kInFront, goaway, (long)w);
  538.         RScurrent->pal = NULL;
  539.         if (RScurrent->window == NULL) {
  540.             VSdestroy(w);
  541.             return(-2);
  542.             }
  543.         }
  544.     else
  545.       {
  546.         short i;
  547.         RGBColor scratchRGB;
  548.         
  549.         RScurrent->window = NewCWindow(0L, wDims, name, showit, (short)8,kInFront, goaway, (long)w);
  550.         if (RScurrent->window == NULL) {
  551.             VSdestroy(w);
  552.             return(-2);
  553.             }
  554.         //note: the ANSI colors are in the top 8 of the palette.  The four telnet colors (settable
  555.         //in telnet) are in the lower 4 of the palette.  These 4 are set later by a call from 
  556.         //CreateConnectionFromParams to RSsetColor (ick, but I am not going to add 4 more params to
  557.         //this ungodly function call (CCP 2.7)
  558.         ourColorTableHdl = (CTabHandle) myNewHandle((long) (sizeof(ColorTable) + 
  559.                                     PALSIZE * sizeof(CSpecArray)));
  560.         if (ourColorTableHdl == NULL) 
  561.         {
  562.             DisposeWindow(RScurrent->window);
  563.             VSdestroy(w);
  564.             return(-2);
  565.         }
  566.         HLock((Handle) ourColorTableHdl);
  567.             
  568.         (*ourColorTableHdl)->ctSize = PALSIZE-1;        // Number of entries minus 1
  569.         (*ourColorTableHdl)->ctFlags = 0;
  570.         
  571.         for (i=0; i <4; i++) //set the ctTable.value field to zero for our four
  572.             (*ourColorTableHdl)->ctTable[i].value = 0;
  573.         
  574.         if (TelInfo->AnsiColors==NULL) 
  575.             return(-2); //BUGG CHANGE THIS ONCE WE ARE WORKING
  576.         
  577.         for (i=0; i < MAXATTR*2; i++) //get the ANSI colors from the palette
  578.         {
  579.             GetEntryColor(TelInfo->AnsiColors, i, &scratchRGB);
  580.             (*ourColorTableHdl)->ctTable[i+4].rgb = scratchRGB;
  581.             (*ourColorTableHdl)->ctTable[i+4].value = 0;
  582.         }
  583.         
  584.         RScurrent->pal = NewPalette(PALSIZE, ourColorTableHdl, pmCourteous, 0);
  585.         DisposeHandle((Handle) ourColorTableHdl);
  586.         if (RScurrent->pal == NULL) 
  587.         {
  588.             DisposeWindow(RScurrent->window);
  589.             VSdestroy(w);
  590.             return(-2);
  591.         }
  592.         SetPalette(RScurrent->window, RScurrent->pal, TRUE); //copy the palette to the window
  593.     } 
  594.  
  595.     SetPort(RScurrent->window);
  596.     SetOrigin(CHO, CVO);            /* Cheap way to correct left margin problem */
  597.  
  598.     wpeek = (WindowPeek) RScurrent->window;
  599.  
  600.     HLock(wpeek->dataHandle);
  601.     wstate = (WStateData *) *wpeek->dataHandle;
  602.  
  603.  
  604.     BlockMove(&wstate->userState, wDims, 8);
  605.     pRect.top = wDims->top;
  606.     pRect.left = wDims->left;
  607.     pRect.right = pRect.left + RMAXWINDOWWIDTH;
  608.     if (pRect.right > TelInfo->screenRect.right)
  609.         pRect.right = TelInfo->screenRect.right;
  610.  
  611.     pRect.bottom = pRect.top + RMAXWINDOWHEIGHT;
  612.     BlockMove(&wstate->stdState, &pRect, 8);
  613.  
  614.   /* create scroll bars for window */
  615.     pRect.top = -1 + CVO;
  616.     pRect.bottom = wheight - 14 + CVO;
  617.     pRect.left = wwidth - 15 + CHO;
  618.     pRect.right = wwidth + CHO;
  619.     RScurrent->scroll = NewControl(RScurrent->window, &pRect, "\p", FALSE,    /* BYU LSC */
  620.         0, 0, 0, 16, 1L);
  621.  
  622.     if (RScurrent->scroll == 0L) return(-3);
  623.  
  624.     pRect.top = wheight - 15 + CVO;
  625.     pRect.bottom = wheight + CVO;
  626.     pRect.left = -1 + CHO;
  627.     pRect.right = wwidth - 14 + CHO;
  628.     RScurrent->left = NewControl(RScurrent->window, &pRect, "\p", FALSE,        /* BYU LSC */
  629.         0, 0, 0, 16, 1L);
  630.  
  631.     if (RScurrent->left == 0L) return(-3);
  632.  
  633.     RScurrent->skip = 0; /* not skipping output initially */
  634.     RScurrent->max = 0; /* scroll bar settings will be properly initialized by subsequent call to VSsetrgn */
  635.     RScurrent->min = 0;
  636.     RScurrent->current = 0;
  637.     RScurrent->lmax = 0;
  638.     RScurrent->lmin = 0;
  639.     RScurrent->lcurrent = 0;
  640.     RScurrent->selected = 0;    /* no selection initially */
  641.     RScurrent->cursorstate = 0;    /* BYU 2.4.11 - cursor off initially */
  642.     RScurrent->flipped = 0;        /* Initially, the color entries are not flipped */
  643.     RSsetsize(w, wheight, wwidth);
  644.  
  645.     RSTextFont(RScurrent->fnum,RScurrent->fsiz,0);    /* BYU LSC */
  646.     TextSize(RScurrent->fsiz);                /* 9 point*/
  647.     if (!TelInfo->haveColorQuickDraw)
  648.         TextMode(srcXor);            /* Xor mode*/
  649.     else
  650.         TextMode(srcCopy);
  651.  
  652.     if (wrapon)
  653.       /* turn on autowrap */
  654.         VSwrite(w, "\033[?7h",5);
  655.  
  656.     return(w);
  657.   } /* RSnewwindow */
  658.  
  659. short RSmouseintext                /* Point is in global coords */
  660.   (
  661.     short w,
  662.     Point myPoint
  663.   )
  664.   /* is myPoint within the text-display area of the specified window. */
  665.   {
  666.     return
  667.         PtInRect(myPoint, &RSlocal[w].textrect);     /* BYU LSC */
  668.   } /* RSmouseintext */
  669.  
  670. void RSkillwindow
  671.   (
  672.     short w
  673.   )
  674.   /* closes a terminal window. */
  675.   {
  676.      WindRecPtr tw;
  677.      RSdata *temp = RSlocal + w;
  678.  
  679.      tw = &screens[findbyVS(w)];
  680.      --((*topLeftCorners)[tw->positionIndex]); //one less window at this position
  681.  
  682.      if (temp->pal != NULL) {
  683.          DisposePalette(temp->pal);        
  684.          temp->pal = NULL;
  685.         }
  686.  
  687.     VSdestroy(w);        /* destroy the virtual screen */
  688.     KillControls(RSlocal[w].window);  /* Get rid of those little slidy things */
  689.     DisposeWindow(RSlocal[w].window);    /* Get rid of the actual window */
  690.     RSlocal[w].window = 0L;
  691.     RSw = -1;
  692.   }
  693.  
  694. RGBColor RSgetcolor
  695.   (
  696.     short w, /* window number */
  697.     short n /* color entry number */
  698.   )
  699.   /* gets the current value for the specified color entry of a terminal window. */
  700.   {
  701.     RGBColor theColor;
  702.     GetEntryColor(RSlocal[w].pal,n,&theColor);
  703.     return theColor;
  704.   
  705.   } /* RSgetcolor */
  706.  
  707. void    RShide( short w)        /* hides a terminal window. */
  708. {
  709.     if (RSsetwind(w) < 0)
  710.         return;
  711.     
  712.     HideWindow(RScurrent->window);
  713. }
  714.  
  715. GrafPtr RSgetwindow
  716.   (
  717.     short w
  718.   )
  719.   /* returns a pointer to the Mac window structure for the
  720.     specified terminal window. */
  721.   {
  722.     return(RSlocal[w].window);
  723.   } /* RSgetwindow */
  724.  
  725. char **RSGetTextSel
  726.   (
  727.     short w, /* window to look at */
  728.     short table /* nonzero for "table" mode, i e
  729.         replace this many (or more) spaces with a single tab. */
  730.   )
  731.   /* returns the contents of the current selection as a handle,
  732.     or nil if there is no selection. */
  733.   {
  734.     char **charh, *charp;
  735.     short maxwid;
  736.     long realsiz;
  737.     Point Anchor,Last;
  738.  
  739.     if (!RSlocal[w].selected)
  740.         return(0L);    /* No Selection */
  741.     maxwid = VSmaxwidth(w);
  742.     Anchor = RSlocal[w].anchor;
  743.     Last = RSlocal[w].last;
  744.     
  745.     realsiz = Anchor.v - Last.v;
  746.     if (realsiz < 0)
  747.         realsiz = - realsiz;
  748.     realsiz ++;                                /* lines 2,3 selected can be 2 lines */
  749.     realsiz *= (maxwid + 2);
  750.     charh = myNewHandle(realsiz);
  751.     if (charh == 0L)
  752.         return((char **) -1L);                /* Boo Boo return */
  753.     HLock((Handle)charh);
  754.     charp = *charh;
  755.     realsiz = VSgettext(w, Anchor.h, Anchor.v, Last.h, Last.v,
  756.         charp, realsiz, "\015", table);
  757.     HUnlock((Handle)charh);
  758.     mySetHandleSize((Handle)charh, realsiz);
  759.     return(charh);
  760.   }  /* RSGetTextSel */
  761.  
  762. RgnHandle RSGetTextSelRgn(short w)
  763. {
  764.     Rect    temp, temp2;
  765.     Point    lb, ub;
  766.     Point    curr;
  767.     Point    last;
  768.     RgnHandle    rgnH, tempRgn;
  769.  
  770.     rgnH = NewRgn();
  771.     if (rgnH == nil) {
  772.         return nil;
  773.         }
  774.  
  775.     tempRgn = NewRgn();
  776.     if (tempRgn == nil) {
  777.         DisposeRgn(rgnH);
  778.         return nil;
  779.         }
  780.  
  781.     RSsetwind(w);
  782.  
  783.     curr = RSlocal[w].anchor;
  784.     last = RSlocal[w].last;
  785.  
  786.   /* normalize coordinates with respect to visible area of virtual screen */
  787.     curr.v -= RScurrent->topline;
  788.     curr.h -= RScurrent->leftmarg;
  789.     last.v -= RScurrent->topline;
  790.     last.h -= RScurrent->leftmarg;
  791.  
  792.     if (curr.v == last.v)
  793.       {
  794.       /* highlighted text all on one line */
  795.         if (curr.h < last.h) /* get bounds the right way round */
  796.           {
  797.             ub = curr;
  798.             lb = last;
  799.           }
  800.         else
  801.           {
  802.             ub = last;
  803.             lb = curr;
  804.           } /* if */
  805.         MYSETRECT /* set up rectangle bounding area to be highlighted */
  806.           (
  807.             temp,
  808.             (ub.h + 1) * RScurrent->fwidth,
  809.             ub.v * RScurrent->fheight,
  810.             (lb.h + 1) * RScurrent->fwidth,
  811.             (lb.v + 1) * RScurrent->fheight
  812.           );
  813.         SectRect(&temp, &noConst, &temp2); /* clip to constraint rectangle */
  814.         RectRgn(rgnH, &temp2);
  815.       }
  816.     else
  817.       {
  818.       /* highlighting across more than one line */
  819.         if (curr.v < last.v)
  820.             ub = curr;
  821.         else
  822.             ub = last;
  823.         if (curr.v > last.v)
  824.             lb = curr;
  825.         else
  826.             lb = last;
  827.         MYSETRECT /* bounds of first (possibly partial) line to be highlighted */
  828.           (
  829.             temp,
  830.             (ub.h + 1) * RScurrent->fwidth,
  831.             ub.v * RScurrent->fheight,
  832.             RScurrent->width,
  833.             (ub.v + 1) * RScurrent->fheight
  834.           );
  835.         SectRect(&temp, &noConst, &temp2); /* clip to constraint rectangle */
  836.         RectRgn(rgnH, &temp2);
  837.  
  838.         MYSETRECT /* bounds of last (possibly partial) line to be highlighted */
  839.           (
  840.             temp,
  841.             0,
  842.             lb.v * RScurrent->fheight,
  843.             (lb.h + 1) * RScurrent->fwidth,
  844.             (lb.v + 1) * RScurrent->fheight
  845.           );
  846.         SectRect(&temp, &noConst, &temp2); /* clip to constraint rectangle */
  847.         RectRgn(tempRgn, &temp2);
  848.         UnionRgn(tempRgn, rgnH, rgnH);
  849.  
  850.         if (lb.v - ub.v > 1) /* highlight extends across more than two lines */
  851.           {
  852.           /* highlight complete in-between lines */
  853.             SetRect
  854.               (
  855.                 &temp,
  856.                 0,
  857.                 (ub.v + 1) * RScurrent->fheight,
  858.                 RScurrent->width,
  859.                 lb.v * RScurrent->fheight
  860.               );
  861.             SectRect(&temp, &noConst, &temp2); /* clip to constraint rectangle */
  862.             RectRgn(tempRgn, &temp2);
  863.             UnionRgn(tempRgn, rgnH, rgnH);
  864.  
  865.           } /* if */
  866.       } /* if */
  867.  
  868.     DisposeRgn(tempRgn);
  869.     
  870.     return rgnH;
  871. }
  872.  
  873. short RSfindvwind
  874.   (
  875.     GrafPtr wind
  876.   )
  877.   /* returns the number of the virtual screen associated with
  878.     the specified window, or -4 if not found. */
  879.   {
  880.     short
  881.         i = 0;
  882.     while ((RSlocal[i].window != wind) && (i < MaxRS))
  883.         i++;
  884.     if ((RSlocal[i].window == 0L) || (i >= MaxRS))
  885.         return(-4);
  886.     else
  887.         return(i);
  888.   } /* RSfindvwind */
  889.  
  890. void RSdeactivate
  891.   (
  892.     short w
  893.   )
  894.  /* handles a deactivate event for the specified window. */
  895.   {
  896.     GrafPtr port;
  897.     GetPort(&port);
  898.     SetPort(RSlocal[w].window);
  899.  
  900.     RSsetConst(w);
  901.   /* update the appearance of the grow icon */
  902.     DrawGrowIcon(RSlocal[w].window); 
  903.   /* and deactivate the scroll bars */
  904.     BackColor(whiteColor);
  905.     if (RSlocal[w].scroll != 0L)
  906.         HideControl(RSlocal[w].scroll);
  907.     if (RSlocal[w].left != 0L)
  908.         HideControl(RSlocal[w].left);
  909.     if (TelInfo->haveColorQuickDraw)
  910.         PmBackColor(1);
  911.     else
  912.         BackColor(blackColor);
  913.      SetPort(port);
  914.   } /* RSdeactivate */
  915.  
  916. void    RScursblink( short w)        /* Blinks the cursor */
  917. {
  918.     GrafPtr    oldwindow;
  919.     long    now = TickCount();
  920.     
  921.     if (now > TelInfo->blinktime) {
  922.         if (VSvalids(w) != 0)            /* BYU 2.4.12 */
  923.             return;                        /* BYU 2.4.12 */
  924.         if (!VSIcursorvisible())        /* BYU 2.4.12 */
  925.             return;                        /* BYU 2.4.12 - cursor isn't visible */
  926.     
  927.         GetPort(&oldwindow);            /* BYU 2.4.11 */
  928.         TelInfo->blinktime = now + 40;    /* BYU 2.4.11 */
  929.         RSlocal[w].cursorstate ^= 1;     /* BYU 2.4.11 */
  930.         SetPort(RSlocal[w].window);        /* BYU 2.4.11 */
  931.         InvertRect(&RSlocal[w].cursor);    /* BYU 2.4.11 */
  932.         SetPort(oldwindow);                /* BYU 2.4.11 */
  933.     }
  934. } /* RScursblink */
  935.  
  936. void RScursblinkon                        /* BYU 2.4.18 */
  937.   (                                        /* BYU 2.4.18 */
  938.     short w                                /* BYU 2.4.18 */
  939.   )                                        /* BYU 2.4.18 */
  940.   /* Blinks the cursor */                /* BYU 2.4.18 */
  941.   {                                        /* BYU 2.4.18 */
  942.       if (!RSlocal[w].cursorstate) {        /* BYU 2.4.18 */
  943.         GrafPtr oldwindow;                /* BYU 2.4.18 */
  944.         GetPort(&oldwindow);            /* BYU 2.4.18 */
  945.         RSlocal[w].cursorstate = 1;     /* BYU 2.4.18 */
  946.         SetPort(RSlocal[w].window);        /* BYU 2.4.18 */
  947.         InvertRect(&RSlocal[w].cursor);    /* BYU 2.4.18 */
  948.         SetPort(oldwindow);                /* BYU 2.4.18 */
  949.     }                                    /* BYU 2.4.18 */
  950.   } /* RScursblink */                    /* BYU 2.4.18 */
  951.  
  952. void RScursblinkoff                        /* BYU 2.4.11 */
  953.   (                                        /* BYU 2.4.11 */
  954.     short w                                /* BYU 2.4.11 */
  955.   )                                        /* BYU 2.4.11 */
  956.   /* Blinks the cursor */                /* BYU 2.4.11 */
  957.   {                                        /* BYU 2.4.11 */
  958.       if (RSlocal[w].cursorstate) {        /* BYU 2.4.11 */
  959.         GrafPtr oldwindow;                /* BYU 2.4.11 */
  960.         GetPort(&oldwindow);            /* BYU 2.4.11 */
  961.         RSlocal[w].cursorstate = 0;     /* BYU 2.4.11 */
  962.         SetPort(RSlocal[w].window);        /* BYU 2.4.11 */
  963.         InvertRect(&RSlocal[w].cursor);    /* BYU 2.4.11 */
  964.         SetPort(oldwindow);                /* BYU 2.4.11 */
  965.     }                                    /* BYU 2.4.11 */
  966.   } /* RScursblink */                    /* BYU 2.4.11 */
  967.  
  968. void    RScprompt(short w)
  969.   /* puts up the dialog that lets the user examine and change the color
  970.     settings for the specified window. */
  971. {
  972.     short        scratchshort, ditem;
  973.     Point        ColorBoxPoint;
  974.     DialogPtr    dptr;
  975.     Boolean        UserLikesNewColor;
  976.     RGBColor    scratchRGBcolor;
  977.     
  978.     dptr = GetNewMySmallDialog(ColorDLOG, NULL, kInFront, (void *)ThirdCenterDialog);
  979.  
  980.     for (scratchshort = 0, NumberOfColorBoxes = 4; scratchshort < NumberOfColorBoxes; scratchshort++)
  981.     {
  982.         RGBColor tempColor;
  983.         tempColor = RSgetcolor(w,scratchshort);
  984.         BoxColorItems[scratchshort] = ColorNF + scratchshort;
  985.         BlockMove(&tempColor,&BoxColorData[scratchshort], sizeof(RGBColor));
  986.         UItemAssign( dptr, ColorNF + scratchshort, ColorBoxItemProcUPP);
  987.     }
  988.         
  989.     ColorBoxPoint.h = 0;            // Have the color picker center the box on the main
  990.     ColorBoxPoint.v = 0;            // screen
  991.     
  992.     ditem = 3;    
  993.     while (ditem > 2) {
  994.         ModalDialog(ColorBoxModalProcUPP, &ditem);
  995.         switch (ditem) {
  996.             case    ColorNF:    
  997.             case    ColorNB:    
  998.             case    ColorBF:    
  999.             case    ColorBB:    
  1000.                 if (TelInfo->haveColorQuickDraw) {
  1001.                     Str255 askColorString;
  1002.                     GetIndString(askColorString,MISC_STRINGS,PICK_NEW_COLOR_STRING);
  1003.                     UserLikesNewColor = GetColor(ColorBoxPoint, askColorString,
  1004.                          &BoxColorData[ditem-ColorNF], &scratchRGBcolor);
  1005.                     if (UserLikesNewColor)
  1006.                         BoxColorData[ditem-ColorNF] = scratchRGBcolor;
  1007.                     }
  1008.                 break;
  1009.                 
  1010.             default:
  1011.                 break;
  1012.             
  1013.             } // switch
  1014.         } // while
  1015.  
  1016.     if (ditem == DLOGCancel) {
  1017.         DisposeDialog(dptr);
  1018.         return;
  1019.         }
  1020.         
  1021.     for (scratchshort = 0; scratchshort < NumberOfColorBoxes; scratchshort++) 
  1022.             RSsetcolor(w,scratchshort,BoxColorData[scratchshort]);
  1023.     
  1024.     /* force redrawing of entire window contents */
  1025.     SetPort(RSlocal[w].window);
  1026.     InvalRect(&RSlocal[w].window->portRect);
  1027.  
  1028.     DisposeDialog(dptr);
  1029. } /* RScprompt */
  1030.  
  1031. /*------------------------------------------------------------------------------*/
  1032. /* NCSA: SB - RScalcwsize                                                         */
  1033. /*         This routine is used to switch between 80 and 132 column mode. All that    */    
  1034. /*         is passed in is the RS window, and the new width.  This calculates the    */    
  1035. /*         new window width, resizes the window, and updates everything.  - SMB    */
  1036. /*------------------------------------------------------------------------------*/
  1037. void RScalcwsize(short w, short width)
  1038. {
  1039.     short x1,x2,y1,y2;
  1040.     short lines;
  1041.     short resizeWidth, resizeHeight;
  1042.     Rect ourContent;
  1043.     
  1044.     RSsetwind(w);
  1045.     RScursoff(w);
  1046.     VSsetcols(w,(short)(width-1));
  1047.     VSgetrgn(w, &x1, &y1, &x2, &y2); /*get current visible region */
  1048.     x2= width-1;
  1049.     lines = VSgetlines(w);                /* NCSA: SB - trust me, you need this... */
  1050.     RScurrent->rwidth =
  1051.         RScurrent->width = (x2 - x1 + 1) * RScurrent->fwidth - CHO;
  1052.     RScurrent->rheight =
  1053.         RScurrent->height= (y2 - y1 + 1) * RScurrent->fheight; 
  1054.  
  1055.  
  1056.     if (RScurrent->rwidth > RMAXWINDOWWIDTH - 16 - CHO)
  1057.           RScurrent->rwidth = RMAXWINDOWWIDTH - 16 - CHO;
  1058.     if (RScurrent->rheight > RMAXWINDOWHEIGHT - 16)
  1059.           RScurrent->rheight = RMAXWINDOWHEIGHT - 16;
  1060.  
  1061.     ourContent = (*((WindowPeek)(RScurrent->window))->contRgn)->rgnBBox;    
  1062.     RScheckmaxwind(&ourContent,RScurrent->rwidth +16,    
  1063.                 RScurrent->rheight + 16, &resizeWidth, &resizeHeight);        
  1064.     RScurrent->rwidth = resizeWidth - 16;
  1065.     RScurrent->rheight = resizeHeight - 16;
  1066.     SizeWindow
  1067.       (
  1068.         RScurrent->window,
  1069.         RScurrent->rwidth + 16, RScurrent->rheight+16,
  1070.         FALSE
  1071.       ); 
  1072.     RSsetsize(w, RScurrent->rheight + 16, RScurrent->rwidth + 16);
  1073.     VSgetrgn(w, &x1, &y1, &x2, &y2);
  1074.     VSsetrgn(w, x1, y1,
  1075.         (short) (x1 + (RScurrent->rwidth ) / RScurrent->fwidth - 1),
  1076.         (short) (y1 + (RScurrent->rheight) / RScurrent->fheight - 1));
  1077.     VSgetrgn(w, &x1, &y1, &x2, &y2);        /* Get new region */
  1078.     
  1079.     DrawGrowIcon(RScurrent->window);
  1080.     VSredraw(w, 0, 0, x2 - x1 + 1, y2 - y1 + 1); /* redraw newly-revealed area, if any */
  1081.     ValidRect(&RScurrent->window->portRect); /* no need to do it again */
  1082.     DrawControls(RScurrent->window);
  1083.     
  1084.     RScursoff(w);
  1085. }
  1086.  
  1087. /* handles a click in a terminal window. */
  1088. short RSclick( GrafPtr window, EventRecord theEvent)
  1089. {
  1090.     ControlHandle ctrlh;
  1091.     short w, part, part2, x1, x2, y1, y2;
  1092.     Point    where = theEvent.where;
  1093.     
  1094.     short    shifted = (theEvent.modifiers & shiftKey);
  1095.     short    optioned = (theEvent.modifiers & optionKey);
  1096.     
  1097.     w = 0;
  1098.     while ((RSlocal[w].window != window) && (w < MaxRS))    //find VS 
  1099.         w++;
  1100.     if ((RSlocal[w].window == 0L) || (w >= MaxRS))
  1101.         return(-1); /* what the heck is going on here?? */
  1102.  
  1103.  
  1104.     SetPort(window);
  1105.     GlobalToLocal((Point *) &where);
  1106.     part = FindControl(where, window, &ctrlh);        /* BYU LSC */
  1107.     if (part != 0)
  1108.         switch (part)
  1109.           {
  1110.             case inThumb:
  1111.                 part2 = TrackControl(ctrlh, where, 0L);        /* BYU LSC */
  1112.                 if (part2 == inThumb)
  1113.                   {
  1114.                     part = GetCtlValue(ctrlh);
  1115.                     if (ctrlh == RSlocal[w].scroll)
  1116.                       {
  1117.                       /* scroll visible region vertically */
  1118.                         VSgetrgn(w, &x1, &y1, &x2, &y2);
  1119.                         VSsetrgn(w, x1, part, x2, part + (y2 - y1));
  1120.                       }
  1121.                     else
  1122.                       { /* ctrlh must be .left */
  1123.                       /* scroll visible region horizontally */
  1124.                         VSgetrgn(w, &x1, &y1, &x2, &y2);
  1125.                         VSsetrgn(w, part, y1, part + (x2 - x1), y2);
  1126.                       } /* if */
  1127.                   } /* if */
  1128.                 break;
  1129.             case inUpButton:
  1130.             case inDownButton:
  1131.             case inPageUp:
  1132.             case inPageDown:
  1133.                 part2 = TrackControl(ctrlh, where, ScrollProcUPP);    /* BYU LSC */
  1134.     /*            InvalRect(&(**RSlocal->scroll).contrlRect); */  /* cheap fix */
  1135.                 break;
  1136.             default:
  1137.                 break;
  1138.           } /* switch */
  1139.     else
  1140.     {
  1141.         if ((where.h <= RSlocal[w].width)&&(where.v <= RSlocal[w].height))
  1142.         {//CCP 2.7 added the above check so that we dont do things when we are in an inactive scrollbar
  1143.             if (optioned) 
  1144.             {
  1145.               /* send host the appropriate sequences to move the cursor
  1146.                 to the specified position */
  1147.                 Point x;
  1148.                 x = normalize(where, w,FALSE);
  1149.                 VSpossend(w, x.h, x.v, screens[scrn].echo); /* MAT--we can check here if we want to use normal */
  1150.                                                             /* MAT--or EMACS movement. */
  1151.             }
  1152.             else if (ClickInContent(where,w))         /* NCSA: SB - prevent BUS error */
  1153.             {
  1154.                 Boolean    dragged;
  1155.     
  1156.                 (void) DragText(&theEvent, where, w, &dragged);
  1157.                 if (!dragged) 
  1158.                     RSselect(w, where, theEvent);
  1159.             }
  1160.         }
  1161.       } /* if */
  1162.     return
  1163.         0;
  1164.   } /* RSclick */
  1165.  
  1166. void RSactivate
  1167.   (
  1168.     short w
  1169.   )
  1170.   /* handles an activate event for the specified window. */
  1171.   {
  1172.     RSsetConst(w);
  1173.   /* display the grow icon */
  1174.     DrawGrowIcon(RSlocal[w].window);
  1175.   /* and activate the scroll bars */
  1176.     if (RSlocal[w].scroll != 0L)
  1177.         ShowControl(RSlocal[w].scroll);
  1178.     if (RSlocal[w].left != 0L)
  1179.         ShowControl(RSlocal[w].left);
  1180.   } /* RSactivate */
  1181.  
  1182. /*--------------------------------------------------------------------------*/
  1183. /* HandleDoubleClick                                                        */
  1184. /* This is the routine that does the real dirty work.  Since it is not a    */
  1185. /* true TextEdit window, we have to kinda "fake" the double clicking.  By    */
  1186. /* this time, we already know that a double click has taken place, so check    */
  1187. /* the chars to the left and right of our location, and select all chars     */
  1188. /* that are appropriate    -- SMB                                                */
  1189. /*--------------------------------------------------------------------------*/
  1190. static    void HandleDoubleClick(short w, short modifiers)                                                    
  1191. {                                                                                
  1192.     Point    leftLoc, rightLoc, curr, oldcurr;                                                    
  1193.     long    mySize;                                                            
  1194.     char    theChar[5];                                                            
  1195.     short    mode = -1, newmode, foundEnd=0;                                                            
  1196.     RSsetConst(w);                                                                /* get window dims */                            
  1197.     leftLoc = RSlocal[w].anchor;                                    /* these two should be the same */                            
  1198.     rightLoc = RSlocal[w].last;                                    
  1199.                                                                                 
  1200.     while(!foundEnd)                                                            /* scan to the right first */                                                        
  1201.         {                                                                        
  1202.         mySize = VSgettext(w,rightLoc.h, rightLoc.v, rightLoc.h+1, rightLoc.v,    
  1203.             theChar,(long)1,"\015",0);                                    
  1204.         if(mySize ==0 || isspace(*theChar))                                    /* stop if not a letter */            
  1205.             foundEnd =1;                                                        
  1206.         else rightLoc.h++;                                                        
  1207.         }                                                                        
  1208.                                                                                 
  1209.     foundEnd =0;                                                                
  1210.     while(!foundEnd)                                                            /* ...and then scan to the left */                                                            
  1211.         {                                                                        
  1212.         mySize = VSgettext(w,leftLoc.h-1, leftLoc.v, leftLoc.h, leftLoc.v,        
  1213.             theChar,(long)1,"\015",0);                                    
  1214.         if(mySize ==0 || isspace(*theChar))                                        /* STOP! */        
  1215.             foundEnd =1;                                                        
  1216.         else leftLoc.h--;                                                        
  1217.         }                                                                        
  1218.                                                                                 
  1219.     if (leftLoc.h != rightLoc.h) {        /* we selected something */
  1220.         RSlocal[w].anchor = leftLoc;    /* new left bound */
  1221.         RSlocal[w].last = rightLoc;        /* and a matching new right bound */
  1222.         RSlocal[w].selected = 1;        /* give me credit for the selection I just made */
  1223.         RSinvText(w, RSlocal[w].anchor,        /* time to show it off */
  1224.             RSlocal[w].last, &noConst);
  1225.  
  1226.         if (modifiers & cmdKey)        // Possible URL selection
  1227.             HandleURL(w);
  1228.         else {                                                                        
  1229.     
  1230.             curr.h = 0; curr.v = 0;
  1231.     
  1232.             while (StillDown()) {
  1233.               /* wait for mouse position to change */
  1234.                 do {
  1235.                     oldcurr = curr;
  1236.                     curr = normalize(getlocalmouse(RSlocal[w].window), w,TRUE);
  1237.                     } while (EqualPt(curr, oldcurr) && StillDown());
  1238.         
  1239.                 
  1240.                 if ((curr.v < leftLoc.v) || ((curr.v == leftLoc.v) && (curr.h < leftLoc.h))) {
  1241.                     newmode = 1;    // up
  1242.                     }
  1243.                 else if ((curr.v > leftLoc.v) || ((curr.v == leftLoc.v) && (curr.h > rightLoc.h))) {
  1244.                     newmode = 2;    // down
  1245.                     }
  1246.                 else 
  1247.                     newmode = -1;    // inside dbl-clicked word
  1248.                     
  1249.                 /* toggle highlight state of text between current and last mouse positions */
  1250.                 if (mode == -1) {
  1251.                     if (newmode == 2) {
  1252.                         RSlocal[w].anchor = leftLoc;
  1253.                         RSinvText(w, curr, rightLoc, &noConst);
  1254.                         RSlocal[w].last = curr;
  1255.                         }
  1256.                     if (newmode == 1) {
  1257.                         RSlocal[w].anchor = rightLoc;
  1258.                         RSinvText(w, curr, leftLoc, &noConst);
  1259.                         RSlocal[w].last = curr;
  1260.                         }
  1261.                     }
  1262.     
  1263.                 if (mode == 1) {
  1264.                     if (newmode == 2) {
  1265.                         RSlocal[w].anchor = leftLoc;
  1266.                         RSinvText(w, oldcurr, leftLoc, &noConst);
  1267.                         RSinvText(w, rightLoc, curr, &noConst);
  1268.                         RSlocal[w].last = curr;
  1269.                         }
  1270.                     if (newmode == -1) {
  1271.                         RSlocal[w].anchor = leftLoc;
  1272.                         RSinvText(w, oldcurr, leftLoc, &noConst);
  1273.                         RSlocal[w].last = rightLoc;
  1274.                         }
  1275.                     if (newmode == mode) {
  1276.                         RSinvText(w, oldcurr, curr, &noConst);
  1277.                         RSlocal[w].last = curr;
  1278.                         }
  1279.                     }
  1280.                 
  1281.                 if (mode == 2) {
  1282.                     if (newmode == 1) {
  1283.                         RSlocal[w].anchor = rightLoc;
  1284.                         RSinvText(w, oldcurr, rightLoc, &noConst);
  1285.                         RSinvText(w, leftLoc, curr, &noConst);
  1286.                         RSlocal[w].last = curr;
  1287.                         }
  1288.                     if (newmode == -1) {
  1289.                         RSlocal[w].anchor = leftLoc;
  1290.                         RSinvText(w, oldcurr, rightLoc, &noConst);
  1291.                         RSlocal[w].last = rightLoc;
  1292.                         }
  1293.                     if (newmode == mode) {
  1294.                         RSinvText(w, oldcurr, curr, &noConst);
  1295.                         RSlocal[w].last = curr;
  1296.                         }
  1297.                     }
  1298.                     
  1299.                 mode = newmode;
  1300.                 } /* while */
  1301.             }
  1302.         }    
  1303. }
  1304.  
  1305. Point getlocalmouse(GrafPtr wind)
  1306.   /* returns the current mouse position in coordinates local
  1307.     to the specified window. Leaves the current grafPort set
  1308.     to that window. */
  1309.   {
  1310.     Point temp;
  1311.  
  1312.     SetPort(wind);
  1313.     GetMouse(&temp);
  1314.     return(temp);
  1315.   } /* getlocalmouse */
  1316.   
  1317.   /*--------------------------------------------------------------------------*/
  1318. /* NCSA: SB - ClickInContent                                                */
  1319. /*    This procedure is a quick check to see if the mouse click is in the        */
  1320. /*    content region of the window.  Normalize the point to be a VS location    */
  1321. /*     and then see if that is larger than what it should be...                */
  1322. /*    Used by RSClick to see if the click is in the scroll bars, or content..    */
  1323. /*--------------------------------------------------------------------------*/
  1324. short ClickInContent(Point where,short w)                /* NCSA: SB */
  1325. {                                                        /* NCSA: SB */
  1326.     Point x;                                            /* NCSA: SB */
  1327.     x = normalize(where, w,FALSE);                            /* NCSA: SB */
  1328.     if (x.v >= VSgetlines(w)) return 0;                    /* NCSA: SB */
  1329.     else return 1;                                        /* NCSA: SB */
  1330. }                                                        /* NCSA: SB */
  1331.  
  1332. void RSchangefont(short w, short fnum,long fsiz)
  1333.    /*    Set (w) to font fnum, size fsiz; resize window */
  1334. {
  1335.     Rect pRect;
  1336.     short x1, x2, y1, y2, width, lines;
  1337.     short srw,srh;
  1338.     WStateData *wstate;
  1339.     WindowPeek wpeek;
  1340.     short resizeWidth, resizeHeight;        /* NCSA: SB */
  1341.  
  1342.     RSsetwind(w);
  1343.     srw = RScurrent->rwidth;
  1344.     srh = RScurrent->rheight;
  1345.  
  1346.     if (fnum != -1)
  1347.       {
  1348.         RSTextFont(fnum,fsiz,0);    /* BYU */
  1349.         RScurrent->fnum = fnum;
  1350.       } /* if */
  1351.     
  1352.     if (fsiz)
  1353.       {
  1354.         TextSize(fsiz);
  1355.         RScurrent->fsiz = fsiz;
  1356.       } /* if */
  1357.     
  1358.     RSfontmetrics();
  1359.  
  1360.     width = VSmaxwidth(w) + 1;
  1361.     lines = VSgetlines(w);
  1362.     
  1363.  /* resize window to preserve its dimensions in character cell units */
  1364.     
  1365.     VSgetrgn(w, &x1, &y1, &x2, &y2);    /* get visible region */
  1366.     RScurrent->rwidth =
  1367.         RScurrent->width = (x2 - x1 + 1) * RScurrent->fwidth - CHO;
  1368.     RScurrent->rheight =
  1369.         RScurrent->height= (y2 - y1 + 1) * RScurrent->fheight;
  1370.  
  1371.     if (RScurrent->rwidth > RMAXWINDOWWIDTH - 16 - CHO)
  1372.           RScurrent->rwidth = RMAXWINDOWWIDTH - 16 - CHO;
  1373.     if (RScurrent->rheight > RMAXWINDOWHEIGHT - 16)
  1374.           RScurrent->rheight = RMAXWINDOWHEIGHT - 16;
  1375.     
  1376.     RScheckmaxwind(&RScurrent->window->portRect,RScurrent->rwidth +16,    /* NCSA: SB */
  1377.         RScurrent->rheight + 16, &resizeWidth, &resizeHeight);            /* NCSA: SB */
  1378.  
  1379.  
  1380.     SizeWindow
  1381.       (
  1382.         RScurrent->window,
  1383.         RScurrent->rwidth + 16, RScurrent->rheight+16,
  1384.         FALSE
  1385.       ); /*  TRUE if done right */
  1386.     RSsetsize(w, RScurrent->rheight + 16, RScurrent->rwidth + 16);
  1387.  
  1388.     wpeek = (WindowPeek) RScurrent->window;
  1389.  
  1390.     HLock(wpeek->dataHandle);
  1391.     wstate = (WStateData *) *wpeek->dataHandle;
  1392.  
  1393.     BlockMove(&pRect, &wstate->stdState, 8);
  1394.     pRect.right = pRect.left + RMAXWINDOWWIDTH;
  1395.     if (pRect.right > TelInfo->screenRect.right)
  1396.         pRect.right = TelInfo->screenRect.right;
  1397.     pRect.bottom = pRect.top + RMAXWINDOWHEIGHT;
  1398.     BlockMove(&wstate->stdState, &pRect, 8);
  1399.  
  1400.     VSgetrgn(w, &x1, &y1, &x2, &y2);
  1401.     VSsetrgn(w, x1, y1,
  1402.         (short) (x1 + (RScurrent->rwidth ) / RScurrent->fwidth - 1),
  1403.         (short) (y1 + (RScurrent->rheight) / RScurrent->fheight - 1));
  1404.     VSgetrgn(w, &x1, &y1, &x2, &y2);        /* Get new region */
  1405.     
  1406.     DrawGrowIcon(RScurrent->window);
  1407.     VSredraw(w, 0, 0, x2 - x1 + 1, y2 - y1 + 1); /* redraw newly-revealed area, if any */
  1408.     ValidRect(&RScurrent->window->portRect); /* no need to do it again */
  1409.     DrawControls(RScurrent->window);
  1410.   } /* RSchangefont */
  1411.  
  1412. short RSgetfont
  1413.   (
  1414.     short w, /* which window */
  1415.     short *pfnum, /* where to return font ID */
  1416.     short *pfsiz /* where to return font size */
  1417.   )
  1418.   /* returns the current font ID and size setting for the specified window. */
  1419.   {
  1420.     if (0 > RSsetwind(w))
  1421.         return -1;
  1422.     *pfnum = RScurrent->fnum;
  1423.     *pfsiz = RScurrent->fsiz;
  1424.     return(0);
  1425.   } /* RSgetfont */
  1426.  
  1427. void RSfontmetrics
  1428.   (
  1429.     void
  1430.   )
  1431.   /* calculates various metrics for drawing text with selected font
  1432.     and size in current grafport into *RScurrent. */
  1433.   {
  1434.     FontInfo finforec;
  1435.     GrafPtr myGP;
  1436.  
  1437.     GetPort(&myGP); 
  1438.     GetFontInfo(&finforec);
  1439.     RScurrent->fascent = finforec.ascent;
  1440.     RScurrent->fheight = finforec.ascent + finforec.descent + finforec.leading /* +1 */;
  1441.     RScurrent->monospaced = (CharWidth('W') == CharWidth('i'));   
  1442.  
  1443.     RScurrent->fwidth = CharWidth('W'); 
  1444. }
  1445.  
  1446. pascal void ScrollProc(ControlHandle control, short part)
  1447.   /* scroll-tracking routine which does continuous scrolling of visible
  1448.      region. */
  1449.   {
  1450.     short w, kind, x1, y2, x2, y1;
  1451.  
  1452.     kind = RSfindscroll(control, &w);
  1453.     VSgetrgn(w, &x1, &y1, &x2, &y2);
  1454.  
  1455.     if (kind == 2)
  1456.       { /* horizontal scroll bar */
  1457.         switch (part)
  1458.           {
  1459.             case inUpButton:                            /* Up is left */
  1460.                 VSscrolleft(w, 1);
  1461.                 break;
  1462.             case inDownButton:                            /* Down is right */
  1463.                 VSscrolright(w, 1);
  1464.                 break;
  1465.             case inPageUp:
  1466.                 VSscrolleft(w, x2 - x1); /* scroll a whole windowful */
  1467.                 break;
  1468.             case inPageDown:
  1469.                 VSscrolright(w, x2 - x1); /* scroll a whole windowful */
  1470.                 break;
  1471.             default:
  1472.                 break;
  1473.           } /* switch */
  1474.       }
  1475.     else if (kind == 1)
  1476.       { /* vertical scroll bar */
  1477.         switch (part)
  1478.           {
  1479.             case inUpButton:
  1480.                 VSscrolback(w, 1);
  1481.                 break;
  1482.             case inDownButton:
  1483.                 VSscrolforward(w, 1);
  1484.                 break;
  1485.             case inPageUp:
  1486.                 VSscrolback(w, y2 - y1); /* scroll a whole windowful */
  1487.                 break;
  1488.             case inPageDown:
  1489.                 VSscrolforward(w, y2 - y1); /* scroll a whole windowful */
  1490.                 break;
  1491.             default:
  1492.                 break;
  1493.           } /* switch */
  1494.       } /* if */
  1495.   } /* ScrollProc */
  1496.  
  1497. void UnHiliteSelection(short w)
  1498. {
  1499.     RSinvText(w, RSlocal[ w].anchor, RSlocal[w].last, &noConst);
  1500.     RSlocal[w].selected = FALSE;
  1501. }
  1502. void HiliteThis(short w, Point begin, Point end)
  1503. {
  1504.     if (RSlocal[w].selected)
  1505.         UnHiliteSelection(w);
  1506.  
  1507.     RSlocal[w].anchor.v = begin.v;
  1508.     RSlocal[w].anchor.h = begin.h;
  1509.     RSlocal[w].last.v = end.v;
  1510.     RSlocal[w].last.h = end.h;
  1511.     
  1512.     RSinvText(w, RSlocal[ w].anchor, RSlocal[w].last, &noConst);
  1513.     RSlocal[w].selected = TRUE;
  1514. }
  1515.  
  1516. void calculateWindowPosition(WindRec *theScreen,Rect *whereAt, short colsHigh, short colsWide)
  1517. {
  1518.     
  1519.     short offset, currentCount = 0, lastIndex = 0;
  1520.     Boolean done = FALSE, tooFarRight = FALSE;
  1521.     short w = theScreen->vs;
  1522.     Boolean wideCount = 0;
  1523.     theScreen->positionIndex = 0;
  1524.     while (!done)
  1525.     {
  1526.         
  1527.         while (((*topLeftCorners)[theScreen->positionIndex] > currentCount)&& //find an empty spot
  1528.                 (theScreen->positionIndex < MaxSess - 1))
  1529.             theScreen->positionIndex++;
  1530.         
  1531.         offset = ((gApplicationPrefs->StaggerWindows == TRUE) ? 
  1532.                     gApplicationPrefs->StaggerWindowsOffset : 1) * (theScreen->positionIndex);
  1533.         whereAt->top = GetMBarHeight() + 20 + offset;
  1534.         whereAt->left  = 10 + offset;
  1535.         if (!tooFarRight)
  1536.             whereAt->left += (currentCount-wideCount)*gApplicationPrefs->StaggerWindowsOffset;
  1537.         else
  1538.             wideCount += currentCount - 1;
  1539.         whereAt->bottom= 30000 + offset;
  1540.         whereAt->right = 30000 + offset;
  1541.         tooFarRight = (whereAt->left + (colsWide + 1)*RScurrent->fwidth + 16 - CHO >
  1542.                     TelInfo->screenRect.right);
  1543.         if (tooFarRight || (whereAt->top + (colsHigh + 1)*RScurrent->fwidth + 16 - CHO > 
  1544.                                         TelInfo->screenRect.bottom))
  1545.         { // we are off screen
  1546.             if (theScreen->positionIndex == 0)
  1547.                 return; //the window is bigger than the screensize; return;
  1548.             
  1549.             currentCount++; // go through again, pick spot with least number already at it
  1550.             lastIndex = theScreen->positionIndex;
  1551.             theScreen->positionIndex = 0;         
  1552.         }
  1553.         else
  1554.             done = TRUE;
  1555.     }    
  1556.     ((*topLeftCorners)[theScreen->positionIndex])++; //add our window to the number at this spot
  1557. }
  1558.  
  1559. void RSUpdatePalette(void)  //called when ANSI colors have changed, and we need to update each
  1560. {                            //windows palette
  1561.     GrafPtr oldPort;
  1562.     int screenIndex;
  1563.  
  1564.     GetPort(&oldPort);
  1565.     for (screenIndex = 0; screenIndex < TelInfo->numwindows; screenIndex++)
  1566.     {
  1567.         if ((screens[screenIndex].active == CNXN_ACTIVE)||
  1568.             (screens[screenIndex].active == CNXN_OPENING))
  1569.         {
  1570.             if (screens[screenIndex].ANSIgraphics)
  1571.             {
  1572.                 if (RSsetwind(screens[screenIndex].vs) >= 0)
  1573.                 {
  1574.                     int i;
  1575.                     for (i = 1; i < 7; i++) //only do the six that are changeable (not Bl. and Wh)
  1576.                     {
  1577.                             RGBColor tempColor;
  1578.                             GetEntryColor(TelInfo->AnsiColors, i, &tempColor);
  1579.                             SetEntryColor(RScurrent->pal,i+4, &tempColor); //set the new color
  1580.                             SetPort(screens[screenIndex].wind);
  1581.                             InvalRect(&(RScurrent->window->portRect));//force a redraw
  1582.                     }
  1583.                 }
  1584.             }
  1585.         }
  1586.     }
  1587.     SetPort(oldPort);
  1588. }